import qs from 'qs';
import router from '@/router';
import { dynamicRoutes } from '@/router';
import store from '@/store';
import verifications from '@/utils/verifications';
import tools from '@/utils/tools';

const { parseURL, toCamelCase, getToken } = tools;

// 检查某个路径是否存在于当前路由配置中
const pathExistsInRoutes = path => router.getRoutes().some(r => r.path === path);

const whiteList = ['/login', '/404'];
const parentRoute = {
    name: 'Master',
    path: '/',
    redirect: '',
    component: () => import('@/views/master.vue'),
    children: [],
    meta: {},
};

const initRouters = (routes, pId = '0', pathPrefix = '') => {
    const routeList = [];
    routes.forEach(route => {
        let routePath = (route.path || '').split('?')[0];
        if (routePath[0] !== '/') routePath = `/${routePath}`;
        routePath = `${pathPrefix}${routePath}`;
        const meta = {
            title: route.name,
            icon: route.icon,
            hidden: !route.visible,
            noCache: !route.keepAlive,
            alwaysShow: (route.children || []).length === 1 && (route.alwaysShow !== undefined ? route.alwaysShow : true),
        };
        if (route.component && route.component.includes('?')) {
            const [componentName, query] = route.component.split('?');
            route.component = componentName;
            meta.query = qs.parse(query);
        }
        const data = {
            path: routePath,
            name: (route.componentName || '').length ? route.componentName : toCamelCase(route.path, true),
            component: async () => {
                try {
                    const res = await import(`@/views/${route.component}.vue`)
                    return res;
                } catch (error) {
                    console.error(`${route.name}找不到路由页面文件: ${route.component}\n`, error);
                }
            },
            meta: meta,
        }
        if (!route.children && String(route.parentId) === String(pId) && route.component && !verifications.isURL(route.path)) routeList.push(data);
        else if (route.children && route.children.length) routeList.push(...initRouters(route.children, route.id, routePath));
    });
    return routeList;
};

// 路由守卫
router.beforeEach(async (to, from, next) => {
    const hasToken = !!getToken();
    // 白名单直接放行
    if (whiteList.includes(to.path)) {
        if (hasToken && to.path === '/login') {
            next({ path: '/' });
            return;
        }
        next();
        return;
    }
    // 检测是否存在token，将其假设为有效（若无效，在页面调接口会根据401状态码重定向到login页）
    if (hasToken) {
        if (to.path === '/login') {
            next({ path: '/' });
            return;
        }
        // 已经获取过菜单、角色等权限，直接放行
        if (store.state.permissionReady) {
            next();
            return;
        }
        try {
            await store.dispatch('getPermissions');
            const redirectPath = window.decodeURIComponent(from.query.redirect || to.path);
            const nextData = to.path === redirectPath ? { ...to, replace: true } : parseURL(redirectPath);
            if (pathExistsInRoutes(nextData.path)) next(nextData);
            else next({ path: '/404' });
        } catch (errPath) {
            if (errPath) next(errPath);
            else next();
        }
        return;
    }
    next(`/login?redirect=${to.fullPath.replace(/\?redirect=\/[^?]*/, '')}`);
});

export const resetRouter = () => {
    const fullPath = (window.location.href.split('/#') || [])[1];
    const path = fullPath.includes('/login') ? '/login' : `/login?redirect=${fullPath.replace(/\?redirect=\/[^?]*/, '')}`;
    router.push(path);
    const resetWhiteNameList = ['Login', 'NotFind'];
    router.getRoutes().forEach(({ name }) => {
        if (name && !resetWhiteNameList.includes(name)) {
            router.hasRoute(name) && router.removeRoute(name);
        }
    });
}

export const initPermissionRouters = (routes) => {
    parentRoute.children = initRouters(routes).concat(dynamicRoutes);
    router.addRoute(parentRoute);
}